package org.gvp.common.http;

import lombok.Data;
import org.gvp.common.http.query.PagingDateRange;

import java.util.List;

/**
 * 分页数据对象包装类
 * @param <T> 真实数据类型
 */
@Data
public class Page<T> {
    /** 当前页  */
    private int currentPage;
    /** 每页数据量 */
    private int pageSize;
    /** 总数据量 */
    private int total;
    /** 总页数 */
    private int totalPage;
    /** 分页数据 */
    private List<T> data;
    /** 全参构造私有化 */
    private Page(int currentPage, int pageSize, int total, int totalPage, List<T> data) {
        this.currentPage = currentPage;
        this.pageSize = pageSize;
        this.total = total;
        this.totalPage = totalPage;
        this.data = data;
    }
    private Page(){}

    /**
     * 构建一个空的分页对象
     * @return
     * @param <T>
     */
    public static <T> Page<T> buildEmpty(){
        return new Page<T>();
    }

    public static <T> PageBuilder<T> builder(){
        return new PageBuilder<T>();
    }

    /**
     * 分页数据构建器
     * @param <T> 分页数据类型
     */
    public static class PageBuilder<T>{
        private int currentPage;
        private int pageSize;
        private Long total;
        private PagingDateRange range;

        /**
         * (1)设置分页数据总量
         */
        public PageBuilder<T> total(Long total){
            this.total = total;
            return this;
        }
        /**
         * (2)设置当前页码
         */
        public PageBuilder<T> current(int current){
            this.currentPage = current;
            return this;
        }
        /**
         * (3)设置每页数据量
         */
        public PageBuilder<T> pageSize(int pageSize){
            this.pageSize = pageSize;
            return this;
        }

        /**
         * 计算和构建分页数据
         * @param handler 分页数据获取函数
         * @return 分页数据包装类对象
         * @param <T> 分页数据类型
         */
        public <T> Page <T>build(PagingHandler<T> handler){
            int totalPage = this.total.intValue() / this.pageSize + 1;
            List<T> data = handler.handle((this.currentPage - 1) * this.pageSize, this.pageSize);
            return new Page(this.currentPage, this.pageSize, this.total.intValue(), totalPage, data);
        }

        /**
         * 计算和构建分页数据,根据时间区间查找数据
         * @param handler 分页数据获取函数
         * @param <T> 分页数据类型
         * @return 分页数据包装类对象
         */
        public <T> Page <T>buildRange(PageHandlerRange<T> handler){
            int totalPage = this.total.intValue() / this.range.getPageSize() + 1;
            List<T> data = handler.handle((this.range.getCurrentPage() - 1) * this.range.getPageSize(), this.range.getPageSize(),this.range.getStartDate(),this.range.getEndDate());
            return new Page(this.range.getCurrentPage(), this.range.getPageSize(), this.total.intValue(), totalPage, data);
        }

        /**
         * 设置查找日期范围对象
         */
        public PageBuilder<T> dateRange(PagingDateRange range) {
            this.range = range;
            return this;
        }
    }
}
